package com.ncloud.act.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.ncloud.common.exception.UserException;
import com.ncloud.param.service.SequenceService;
import com.ncloud.act.common.ActDataHelper;
import com.ncloud.act.entity.ChnlAccessLog;
import com.ncloud.act.entity.ChnlAdjustBill;
import com.ncloud.act.entity.ChnlBill;
import com.ncloud.act.entity.ChnlDeposit;
import com.ncloud.act.entity.ChnlDetailBill;
import com.ncloud.act.entity.ChnlPayLog;
import com.ncloud.act.entity.ChnlWriteOffLog;
import com.ncloud.act.mapper.ChnlAccessLogMapper;
import com.ncloud.act.mapper.ChnlAdjustBillMapper;
import com.ncloud.act.mapper.ChnlBillMapper;
import com.ncloud.act.mapper.ChnlDepositMapper;
import com.ncloud.act.mapper.ChnlDetailBillMapper;
import com.ncloud.act.mapper.ChnlPayLogMapper;
import com.ncloud.act.mapper.ChnlWriteOffLogMapper;

@Service
public class ChnlPayFeeTransServiceImpl{
	@Resource
	private ChnlPayLogMapper chnlPayLogMapper;
	@Resource
	private ChnlAccessLogMapper chnlAccessLogMapper;
	@Resource
	private ChnlDetailBillMapper chnlDetailBillMapper;
	@Resource
	private ChnlBillMapper chnlBillMapper;
	@Resource
	private ChnlAdjustBillMapper chnlAdjustBillMapper;
	@Resource
	private ChnlWriteOffLogMapper chnlWriteOffLogMapper;
	@Resource
	private ChnlDepositMapper chnlDepositMapper;
	@Reference
	private SequenceService sequenceService;
	@Transactional(propagation=Propagation.REQUIRED)
	public JSONObject chnlPayFee(JSONObject json) throws ParseException{
		//SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
		//Date endDate = df.parse("2050-12-31 23:59:59");
		Long chnl_id           =0l;
		String recv_type        ="1";
		Long recv_fee          =0l;
		Long recv_user_id      =0l;
		String remark      ="";
		if(json.containsKey("chnl_id"))
		{
			chnl_id=json.getLong("chnl_id");
		}else{
			throw new UserException("4000", "没有渠道编码");
		}
		if(json.containsKey("recv_fee"))
		{
			Double dFee=ActDataHelper.toDouble(json.getString("recv_fee"));
			recv_fee=(long)(dFee*100);
		}else{
			throw new UserException("4000", "没有缴费金额");
		}
		if(json.containsKey("userID"))
		{
			recv_user_id=json.getLong("userID");
		}
		if(json.containsKey("remark"))
		{
			remark=json.getString("remark");
		}
		//String sysdate = df.format(new Date());
		//Integer depositCode =0;
		//Long acctBalanceID=0l;
		Long oldDepositMoney = 0l;
		Long oldCreditValue = 0l;
		boolean depositExists = false;
		List<ChnlDeposit> chnlDeposits = chnlDepositMapper.getChnlDepositByChnlID(chnl_id);
		if(null!=chnlDeposits&&chnlDeposits.size()>0)
		{
			ChnlDeposit smap = chnlDeposits.get(0);
			oldDepositMoney=smap.getDeposit_money();
			oldCreditValue=smap.getCredit_value();
			depositExists = true;
		}
		JSONObject param = new JSONObject();
		param.put("seqName", "chnl_charge_id");
		Long charge_id=sequenceService.getSequence(param);
		if(charge_id==0) return null;
		/*if(!depositExists)
		{
			param.put("seqName", "acct_balance_id");
			acctBalanceID=sequenceService.getSequence(param);
		}*/
		//ChnlPayLog表数据组织
		ChnlPayLog chnlPayLog=new ChnlPayLog();
		chnlPayLog.setCharge_id(charge_id);
		chnlPayLog.setChnl_id(chnl_id);
		chnlPayLog.setRecv_type(recv_type);
		chnlPayLog.setRecv_fee(recv_fee);
		//chnlPayLog.setOld_deposit_money(oldDepositMoney);
		//chnlPayLog.setNew_deposit_money(oldDepositMoney+recv_fee);
		chnlPayLog.setRecv_time(new Date());
		chnlPayLog.setRecv_user_id(recv_user_id);
		chnlPayLog.setRemark(remark);
		ChnlDeposit chnlDeposit=new ChnlDeposit();
		if(depositExists)
		{
			chnlDeposit.setChnl_id(chnl_id);
			chnlDeposit.setDeposit_money(oldDepositMoney+recv_fee);
			//chnlDeposit.setInvoice_money(oldInvoiceFee+recv_fee);
			chnlDeposit.setUpdate_time(new Date());
		}else{
			chnlDeposit.setChnl_id(chnl_id);
			chnlDeposit.setDeposit_money(recv_fee);
			chnlDeposit.setCredit_value(oldCreditValue);
			chnlDeposit.setState("1");//0-无效 1-有效
			chnlDeposit.setCreate_time(new Date());
			chnlDeposit.setCreate_user_id(recv_user_id);
			chnlDeposit.setUpdate_time(new Date());
			chnlDeposit.setUpdate_user_id(recv_user_id);
			chnlDeposit.setRemark("");
		}
		//AccessLog表数据组织
		ChnlAccessLog chnlAccessLog=new ChnlAccessLog();
		param.put("seqName", "chnl_access_id");
		Long chnl_access_id=sequenceService.getSequence(param);
		chnlAccessLog.setAccess_id(chnl_access_id);
		chnlAccessLog.setCharge_id(charge_id);
		chnlAccessLog.setChnl_id(chnl_id);
		chnlAccessLog.setOld_deposit_money(oldDepositMoney);
		chnlAccessLog.setMoney(recv_fee);
		chnlAccessLog.setNew_deposit_money(oldDepositMoney+recv_fee);
		chnlAccessLog.setAccess_tag(recv_fee>=0?"0":"1");
		chnlAccessLog.setAdjust_id(0l);
		chnlAccessLog.setRecv_time(new Date());
		chnlAccessLog.setRecv_user_id(recv_user_id);
		chnlAccessLog.setCancel_tag("0");
		//chnlAccessLog.setCancel_time("");
		//chnlAccessLog.setCancel_user_id("");
		chnlAccessLog.setRemark("");
		chnlPayLogMapper.insertChnlPayLog(chnlPayLog);
		if(depositExists)
		{
			chnlDepositMapper.updateChnlDeposit(chnlDeposit);
		}else{
			chnlDepositMapper.insertChnlDeposit(chnlDeposit);
		}
		chnlAccessLogMapper.insertChnlAccessLog(chnlAccessLog);
		//JSONArray results=JSON.parseArray(JSON.toJSONString(payLog));
		json.put("charge_id",charge_id);
		//处理调账信息
		this.chnlAdjustFee(json);
		//销帐
		this.chnlWriteOffFee(json);
		return json;
	}
	private void chnlAdjustFee(JSONObject json) {
		Long chnl_id=0l;
		Long recv_user_id      =0l;
		if(json.containsKey("chnl_id"))
		{
			chnl_id=json.getLong("chnl_id");
		}else{
			throw new UserException("4000", "没有渠道账户编码");
		}
		if(json.containsKey("userID"))
		{
			recv_user_id=json.getLong("userID");
		}
		Long charge_id=0l;
		if(json.containsKey("charge_id"))
		{
			charge_id=json.getLong("charge_id");
		}else{
			throw new UserException("4000", "没有缴费流水");
		}	
		List<ChnlDeposit> chnlDeposits = chnlDepositMapper.getChnlDepositByChnlID(chnl_id);
		if(chnlDeposits==null || chnlDeposits.size()==0){
			return;
		}
		List<ChnlAdjustBill> chnlAdjustBills=chnlAdjustBillMapper.getAdjustBillByChnlID(chnl_id, "1");
		if(chnlAdjustBills==null || chnlAdjustBills.size()==0){
			return;
		}
		for(int i=0;i<chnlDeposits.size();i++)
		{
			ChnlDeposit chnlDeposit = chnlDeposits.get(i);
			Long oldDepositMoney=chnlDeposit.getDeposit_money();
			Long newDepositMoney=chnlDeposit.getDeposit_money();
			for(int billIndex=0;billIndex<chnlAdjustBills.size();billIndex++){
				ChnlAdjustBill chnlAdjustBill=chnlAdjustBills.get(billIndex);
				String adjust_type = chnlAdjustBill.getAdjust_type();
				Long oldAdjustBillBalance=0l;
				Long writeOffMoney=0l;
				Long newAdjustBillBalance=0l;
				//0-调增 1-调减
				if("0".equals(adjust_type)){
					if(newDepositMoney==0){
						break;
					}
					oldAdjustBillBalance=chnlAdjustBill.getAdjust_balance();
					writeOffMoney=(newDepositMoney>oldAdjustBillBalance)?oldAdjustBillBalance:newDepositMoney;
					//newDepositMoney=newDepositMoney-writeOffMoney;
					newAdjustBillBalance=oldAdjustBillBalance-writeOffMoney;
				}else if("1".equals(adjust_type)){
					oldAdjustBillBalance=chnlAdjustBill.getAdjust_balance();
					writeOffMoney=oldAdjustBillBalance;
					//newDepositMoney=newDepositMoney-writeOffMoney;
					newAdjustBillBalance=oldAdjustBillBalance-writeOffMoney;
				}
				chnlAdjustBill.setAdjust_balance(newAdjustBillBalance);
				//0-初始状态 1-未冲正 2-已冲正 3-部分冲正
				String payTag="1";
				if(newAdjustBillBalance==0){
					payTag="2";
				}else{
					payTag="3";
				}
				chnlAdjustBill.setPay_tag(payTag);
				chnlAdjustBill.setUpdate_time(new Date());
				chnlAdjustBill.setUpdate_user_id(recv_user_id);
				chnlAdjustBillMapper.updateChnlAdjustBill(chnlAdjustBill);
				
				ChnlAccessLog chnlAccessLog=new ChnlAccessLog();
				Long chnl_access_id=sequenceService.getSequence("chnl_access_id");
				chnlAccessLog.setAccess_id(chnl_access_id);
				chnlAccessLog.setCharge_id(charge_id);
				chnlAccessLog.setChnl_id(chnl_id);
				chnlAccessLog.setOld_deposit_money(newDepositMoney);
				newDepositMoney=newDepositMoney-writeOffMoney;
				chnlAccessLog.setMoney(-writeOffMoney);
				chnlAccessLog.setNew_deposit_money(newDepositMoney);
				chnlAccessLog.setAccess_tag((newDepositMoney-oldDepositMoney)>=0?"0":"1");
				chnlAccessLog.setAdjust_id(chnlAdjustBill.getAdjust_id());
				chnlAccessLog.setRecv_time(new Date());
				chnlAccessLog.setRecv_user_id(recv_user_id);
				chnlAccessLog.setCancel_tag("0");
				//chnlAccessLog.setCancel_time("");
				//chnlAccessLog.setCancel_user_id("");
				chnlAccessLog.setRemark("");
				chnlAccessLogMapper.insertChnlAccessLog(chnlAccessLog);
			}
			chnlDeposit.setDeposit_money(newDepositMoney);
			chnlDeposit.setUpdate_time(new Date());
			chnlDeposit.setUpdate_user_id(recv_user_id);
			chnlDepositMapper.updateChnlDeposit(chnlDeposit);
		}
	}
	public JSONObject chnlWriteOffFee(JSONObject json) {
		Long chnl_id=0l;
		Long recv_user_id      =0l;
		if(json.containsKey("chnl_id"))
		{
			chnl_id=json.getLong("chnl_id");
		}else{
			throw new UserException("4000", "没有渠道账户编码");
		}
		if(json.containsKey("userID"))
		{
			recv_user_id=json.getLong("userID");
		}
		Long charge_id=0l;
		if(json.containsKey("charge_id"))
		{
			charge_id=json.getLong("charge_id");
		}else{
			throw new UserException("4000", "没有缴费流水");
		}
		//SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//String sysdate = df.format(new Date());
		/*List<ChnlDetailBill> chnlDetailBills = chnlDetailBillMapper.getChnlDetailBillByChnlID(chnl_id);
		if(chnlDetailBills==null || chnlDetailBills.size()==0){
			return null;
		}*/
		List<ChnlDeposit> chnlDeposits = chnlDepositMapper.getChnlDepositByChnlID(chnl_id);
		if(chnlDeposits==null || chnlDeposits.size()==0){
			return null;
		}
		
		List<ChnlBill> chnlBills=chnlBillMapper.getChnlBillByChnlID(chnl_id);
		if(chnlBills==null || chnlBills.size()==0){
			return null;
		}
		
		//Integer tempCycleID=0;
		for(int billIndex=0;billIndex<chnlBills.size();billIndex++){
			ChnlBill chnlBill=chnlBills.get(billIndex);
			Integer billCycleID=chnlBill.getCycle_id();
			Long allWriteOffMoney=0l;
			//渠道一个账期的明细账单
			List<ChnlDetailBill> chnlDetailBills = chnlDetailBillMapper.getChnlDetailBillByChnlID(chnl_id,billCycleID);
			if(chnlDetailBills==null || chnlDetailBills.size()==0){
				return null;
			}
			//=========================================
			for(int i=0;i<chnlDeposits.size();i++)
			{
				ChnlDeposit chnlDeposit = chnlDeposits.get(i);
				Long oldDepositMoney=chnlDeposit.getDeposit_money();
				Long newDepositMoney=chnlDeposit.getDeposit_money();
				for(int j=0;j<chnlDetailBills.size();j++)
				{
					if(newDepositMoney==0){
						break;
					}
					ChnlDetailBill chnlDetailBill = chnlDetailBills.get(j);
					if(chnlDetailBill.getBalance()>0)
					{
						Long oldBillBalance=chnlDetailBill.getBalance();
						Long writeOffMoney=(newDepositMoney>oldBillBalance)?oldBillBalance:newDepositMoney;
						allWriteOffMoney+=writeOffMoney;
						Long newBillBalance=oldBillBalance-writeOffMoney;
						chnlDetailBill.setBalance(newBillBalance);
						String oldBillTag=chnlDetailBill.getBill_tag();
						//0-初始状态 1-出账状态 2-已结清 3-部分结清
						String billPayTag="1";
						if(newBillBalance==0){
							billPayTag="2";
						}else{
							billPayTag="3";
						}
						chnlDetailBill.setBill_tag(billPayTag);
						chnlDetailBill.setUpdate_time(new Date());
						chnlDetailBill.setUpdate_user_id(recv_user_id);
						
						Long writeoff_id=sequenceService.getSequence("chnl_writeoff_id");
						ChnlWriteOffLog chnlWriteOffLog=new ChnlWriteOffLog();
						chnlWriteOffLog.setWriteoff_id(writeoff_id);
						chnlWriteOffLog.setCharge_id(charge_id);
						chnlWriteOffLog.setChnl_id(chnl_id);
						chnlWriteOffLog.setBill_id(chnlDetailBill.getBill_id());
						chnlWriteOffLog.setFee(chnlDetailBill.getFee());
						chnlWriteOffLog.setWriteoff_fee(writeOffMoney);
						chnlWriteOffLog.setOld_balance(oldBillBalance);
						chnlWriteOffLog.setNew_balance(newBillBalance);
						chnlWriteOffLog.setOld_paytag(oldBillTag);
						chnlWriteOffLog.setNew_paytag(billPayTag);
						chnlWriteOffLog.setOperate_time(new Date());
						chnlWriteOffLog.setOperate_user_id(recv_user_id);
						chnlWriteOffLog.setCancel_tag("0");
						chnlWriteOffLog.setRemark("");
						chnlWriteOffLogMapper.insertChnlWriteOffLog(chnlWriteOffLog);
						chnlDetailBillMapper.updateChnlDetailBill(chnlDetailBill);
						ChnlAccessLog chnlAccessLog=new ChnlAccessLog();
						Long chnl_access_id=sequenceService.getSequence("chnl_access_id");
						chnlAccessLog.setAccess_id(chnl_access_id);
						chnlAccessLog.setCharge_id(charge_id);
						chnlAccessLog.setChnl_id(chnl_id);
						chnlAccessLog.setOld_deposit_money(newDepositMoney);
						newDepositMoney=newDepositMoney-writeOffMoney;
						chnlAccessLog.setMoney(-writeOffMoney);
						chnlAccessLog.setNew_deposit_money(newDepositMoney);
						chnlAccessLog.setAccess_tag((newDepositMoney-oldDepositMoney)>=0?"0":"1");
						chnlAccessLog.setAdjust_id(0l);
						chnlAccessLog.setRecv_time(new Date());
						chnlAccessLog.setRecv_user_id(recv_user_id);
						chnlAccessLog.setCancel_tag("0");
						//chnlAccessLog.setCancel_time("");
						//chnlAccessLog.setCancel_user_id("");
						chnlAccessLog.setRemark("");
						chnlAccessLogMapper.insertChnlAccessLog(chnlAccessLog);
					}
				}
				chnlDeposit.setDeposit_money(newDepositMoney);
				chnlDeposit.setUpdate_time(new Date());
				chnlDeposit.setUpdate_user_id(recv_user_id);
				chnlDepositMapper.updateChnlDeposit(chnlDeposit);
			}
			Long billBalance=chnlBill.getBalance()-allWriteOffMoney;
			chnlBill.setBalance(billBalance);
			//0-初始状态 1-出账状态 2-已结清 3-部分结清
			String billTag="1";
			if(billBalance==0){
				billTag="2";
			}else{
				billTag="3";
			}
			chnlBill.setBill_tag(billTag);
			chnlBill.setUpdate_time(new Date());
			chnlBill.setUpdate_user_id(recv_user_id);
			chnlBill.setRemark("");
			chnlBillMapper.updateChnlBill(chnlBill);
			//=========================================
		}
		return json;
	}
}
